/*******************************************************************************
 * File name: 		ssy.c
 * Description: 	system calls for newlib
 * Project: 		_Framework
 * Target: 			LPC2478
 * Compiler: 		arm-none-eabi-gcc
 * Date: 			2011-04-21
 * Author: 			Freddie Chopin
 * Based on: 		---
 ******************************************************************************/

/*==============================================================================
 Includes
==============================================================================*/
#ifdef __cplusplus
extern "C" {
#endif

# include <errno.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/times.h>

/*==============================================================================
 Defines
==============================================================================*/
# define SYSCALLS_HAVE_CLOSE_R		1
# define SYSCALLS_HAVE_EXECVE_R		1
# define SYSCALLS_HAVE_EXIT			1
# define SYSCALLS_HAVE_FORK_R			1
# define SYSCALLS_HAVE_FSTAT_R		1
# define SYSCALLS_HAVE_GETPID_R		1
# define SYSCALLS_HAVE_ISATTY_R		1
# define SYSCALLS_HAVE_KILL_R			1
# define SYSCALLS_HAVE_LINK_R			1
# define SYSCALLS_HAVE_LSEEK_R		1
# define SYSCALLS_HAVE_OPEN_R			1
# define SYSCALLS_HAVE_READ_R			1
# define SYSCALLS_HAVE_SBRK_R			1
# define SYSCALLS_HAVE_STAT_R			1
# define SYSCALLS_HAVE_TIMES_R		1
# define SYSCALLS_HAVE_UNLINK_R		1
# define SYSCALLS_HAVE_WAIT_R			1
# define SYSCALLS_HAVE_WRITE_R		1

/*==============================================================================
 Globals
==============================================================================*/
char *environ_initial[1] = {0};
char **environ = environ_initial;

# undef errno
extern int errno;

/*==============================================================================
 Global function definitions
==============================================================================*/

/*------------------------------------------------------------------------------
 function name:	_close_r
 description:		closes a file
 parameters:		file descriptor
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_CLOSE_R == 1

int _close_r (struct _reent *r, int file)
{
	r = r;									/* suppress warning */
	file = file;							/* suppress warning */

	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_execve_r
 description:		transfers control to a new process
 parameters:		argv is the argument list for the new process image. This should
					contain an array of pointers to character strings, and the array should be
					terminated by a NULL pointer. The value in argv[0] should point to a file
					name that is associated with the process being started by the exec() function

					envp specifies the environment for the new process image. This
					should contain an array of pointers to character strings, and the array
					should be terminated by a NULL pointer
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_EXECVE_R == 1

int _execve_r (struct _reent *r, const char *path, char *const argv[], char *const envp[])
{
	r = r;									/* suppress warning */
	path = path;							/* suppress warning */
	argv = argv;							/* suppress warning */
	envp = envp;							/* suppress warning */

	errno = ENOMEM;
	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_exit
 description:		exit a program
 parameters:		status which represents a termination status
 returned value:	none
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_EXIT == 1

void _exit (int status)
{
	status = status;						/* suppress warning */

	while (1);
}

# endif

/*------------------------------------------------------------------------------
 function name:	_fork_r
 description:		create a new process
 parameters:		pointer to _reent struct
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_FORK_R == 1

pid_t _fork_r (struct _reent *r)
{
	r = r;									/* suppress warning */

	errno = EAGAIN;
	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_fstat_r
 description:		status of an open file
 parameters:		st points to a stat structure where status information about
 	 	 	 	 	 	 the file is to be placed
 returned value:	0 if success
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_FSTAT_R == 1

int _fstat_r (struct _reent *r, int file, struct stat *st)
{
	r = r;									/* suppress warning */
	file = file;							/* suppress warning */
	st = st;									/* suppress warning */

	st->st_mode = S_IFCHR;
	return 0;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_getpid_r
 description:		gets process ID
 parameters:
 returned value:	1 no matter what
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_GETPID_R == 1

pid_t _getpid_r (struct _reent *r)
{
	r = r;									/* suppress warning */

	return 1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_isatty_r
 description:		query whether output stream is a terminal
 parameters:		file descriptor
 returned value:	1 no matter what
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_ISATTY_R == 1

int _isatty_r(struct _reent *r, int file)
{
	r = r;									/* suppress warning */
	file = file;							/* suppress warning */

	return 1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_kill_r
 description:		sends a signal
 parameters:		pid is a process ID or process group ID, signal specifies
 	 	 	 	 	 	 the signal to be sent
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_KILL_R == 1

int _kill_r(struct _reent *r, pid_t pid, int signal)
{
	r = r;									/* suppress warning */
	pid = pid;								/* suppress warning */
	signal = signal;						/* suppress warning */

	errno = EINVAL;
	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_link_r
 description:		set a new name for an existing file
 parameters:		old points to an existing file name, new- new name
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_LINK_R == 1

int _link_r(struct _reent *r, const char *old, const char *new)
{
	r = r;									/* suppress warning */
	old = old;								/* suppress warning */
	new = new;								/* suppress warning */

	errno = EMLINK;
	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_lseek_r
 description:		set position in a file
 parameters:		file descriptor, offset specifies the number of bytes to offset
					 	 the file pointer from a specified file origin, whence start location
 returned value:	0 if success
------------------------------------------------------------------------------*/
#if SYSCALLS_HAVE_LSEEK_R == 1

off_t _lseek_r (struct _reent *r, int file, off_t offset, int whence)
{
	r = r;									/* suppress warning */
	file = file;							/* suppress warning */
	offset = offset;						/* suppress warning */
	whence = whence;						/* suppress warning */

	return 0;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_open_r
 description:		opens a file
 parameters:		pointer to the file name, flags is the bitwise inclusive-OR of the
					 	 file access modes and file status flags, mode specifies permissions
					 	 the file has when it is created
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_OPEN_R == 1

int _open_r (struct _reent *r, const char *pathname, int flags, int mode)
{
	r = r;									/* suppress warning */
	pathname = pathname;					/* suppress warning */
	flags = flags;							/* suppress warning */
	mode = mode;							/* suppress warning */

	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_read_r
 description:		reads from a file
 parameters:		file descriptor, pointer to a data buffer, max bytes number
 returned value:	0 if success
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_READ_R == 1
ssize_t _read_r (struct _reent *r, int file, void *buf, size_t nbyte)
{
	r = r;									/* suppress warning */
	file = file;							/* suppress warning */
	buf = buf;								/* suppress warning */
	nbyte = nbyte;							/* suppress warning */

	return 0;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_sbrk_r
 description:		increase program data space. This version of _sbrk_r() requires the
						heap area to be defined explicitly in linker script with symbols
						__heap_start and __heap_end
 parameters:		requested data space size
 returned value:	pointer to the new data space
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_SBRK_R == 1

caddr_t _sbrk_r (struct _reent *r, int size)
{
	extern char __heap_start;					/* imported from linker script */
	extern char __heap_end;						/* imported from linker script */
	static char *current_heap_end = &__heap_start;
	char *previous_heap_end;

	r = r;											/* suppress warning */

	previous_heap_end = current_heap_end;

	if (current_heap_end + size > &__heap_end)	/* is there enough space on the heap left? */
	{
		errno = ENOMEM;							/* not enough memory left */
		return (caddr_t) -1;						/* return immediatelly */
	}

	current_heap_end += size;					/* increase data space */

	return (caddr_t)previous_heap_end;		/* return requested data space */
}

# endif

/*------------------------------------------------------------------------------
 function name:	_stat_r
 description:		status of a file (by name)
 parameters:		file name, pointer to the struct which contains status info
 returned value:	0 if success
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_STAT_R == 1

int _stat_r (struct _reent *r, const char *pathname, struct stat *st)
{
	r = r;										/* suppress warning */
	pathname = pathname;						/* suppress warning */

	st->st_mode = S_IFCHR;
	return 0;
}

# endif

/*------------------------------------------------------------------------------
 function name:		_times_r
 description:		timing information for a current process
 parameters:		buf points to a tms structure where timing information about
 	 	 	 	 	 	 the process is to be placed
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_TIMES_R == 1

int _times_r (struct _reent *r, struct tms *buf)
{
	r = r;									/* suppress warning */
	buf = buf;								/* suppress warning */

	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_unlink_r
 description:		remove files directory entry
 parameters:		file name which has to be unlinked
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
#if SYSCALLS_HAVE_UNLINK_R == 1

int _unlink_r (struct _reent *r, const char *pathname)
{
	r = r;									/* suppress warning */
	pathname = pathname;					/* suppress warning */

	errno = ENOENT;
	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_wait_r
 description:		wait for a child process
 parameters:		stat_loc specifies the location where the child process' exit
						status is stored
 returned value:	-1 if failure
------------------------------------------------------------------------------*/
# if SYSCALLS_HAVE_WAIT_R == 1

pid_t _wait_r (struct _reent *r, int *stat_loc)
{
	r = r;									/* suppress warning */
	stat_loc = stat_loc;					/* suppress warning */

	errno = ECHILD;
	return -1;
}

# endif

/*------------------------------------------------------------------------------
 function name:	_write_r
 description:
 parameters:		file descriptor, data buffer to write in the file, number of
 	 	 	 	 	 	 bytes
 returned value:	0 if success
------------------------------------------------------------------------------*/
#if SYSCALLS_HAVE_WRITE_R == 1

ssize_t _write_r (struct _reent *r, int file, const void *buf, size_t nbyte)
{
	r = r;									/* suppress warning */
	file = file;							/* suppress warning */
	buf = buf;								/* suppress warning */
	nbyte = nbyte;							/* suppress warning */

	return 0;
}

# endif

#ifdef __cplusplus
}
#endif
/******************************************************************************
* END OF FILE
******************************************************************************/


